const path = require("path")
const fs = require("fs")
const clone = require("git-clone/promise");
const inquirer = require("inquirer"); 
const ora = require("ora")
const chalk = require('chalk')
const handlebars = require("handlebars")
const { projectInstall } = require('pkg-install');


const templates = require("./template-config");

const runPath = process.cwd(); // 当前工作目录


class CreatePrejectClass {
  constructor () {
    this.prejectInfo = {};
    this.packageManager = "";
    this.inquirerOptions = [
      {
        type:"input",
        message:"请输入项目名称：",
        name:"name",
      },
      {
        type:"input",
        message:"请输入项目描述：",
        name:"description",
      },
      {
        type:"input",
        message:"请输入项目作者：",
        name:"author",
      },
      {
        type:"list",
        name:"prejectType",
        choices: this.addPrejectChoices()
      }
    ];
    this.autoInstallOptions = {
      type:"list",
      name:"autoInstall",
      message:"是否自动安装依赖",
      choices:[
        {
            name:"是",
            value:true,
        },
        {
          name:"否",
          value:false,
        }
      ],
      default:true
    };
    this.installToolOptions = {
      type:"list",
      name:"tool",
      message:"请选择安装工具",
      choices:["yarn","npm"],
      default:"yarn"
    }
  }

  /**
  * 添加 项目类型选择
  * @returns 
  */
  addPrejectChoices = () => {
    let choices = []
    Object.keys(templates).forEach((key) => {
      const tpl = templates[key]
      choices.push({
        name:tpl.name,
        value:tpl.value
      })
    })
    return choices
  }

  createCommandAction = async () => {
    // 下载模板
    const downloadPath = path.join(runPath) // 当前工作目录
    const spinner = ora(`开始初始化模板，请稍后...`);
    const res = await inquirer.prompt(this.inquirerOptions); // 终端交互信息
    this.prejectInfo = res;
  
    const prejectPath = path.join(downloadPath,`/${res.name}`) // 项目地址
    console.log(`项目地址为：`,chalk.greenBright(prejectPath));
  
    const repoUrl = res.prejectType
    if(!repoUrl){
      spinner.fail("没有找到相应的模板");
      return
    }
    console.log("repoUrl is:",chalk.greenBright(repoUrl));
  
    spinner.start();
    try{
      await clone(repoUrl,res.name);
      spinner.succeed("初始化模板成功");
      const packagePath = path.join(prejectPath, `/package.json`); // package.json地址
      this.writePackageJson(packagePath,res)
      spinner.succeed("写入package.json成功");
      await this.handleInstall(prejectPath,res);
      this.logCreateSucess()
    }catch(err){
      spinner.fail("初始化模板失败");
      console.log(chalk.redBright(err));
    }finally{
  
    }
  }


  writePackageJson = (filePath,info) => {
    if(fs.existsSync(filePath)){
      let content = JSON.parse(fs.readFileSync(filePath).toString());
      content.name = '{{ name }}';
      content.description = '{{ description }}';
      content.author = '{{ author }}';
      const templateRender = handlebars.compile(JSON.stringify(content));
      fs.writeFileSync(filePath, templateRender(info));
    }
  }


  handleInstall = async (filePath,info) => {
    const { autoInstall } = await inquirer.prompt(this.autoInstallOptions)
    if(autoInstall){
      const { tool } = await inquirer.prompt(this.installToolOptions);
      this.packageManager = tool;
      const spinner = ora();
      console.log(`正在安装${chalk.greenBright(this.prejectInfo.name)}项目依赖,请稍等......`);
      const res = await this.installFuc({
        info,
        filePath,
        packageManager: tool
      })
      if(res){
        spinner.succeed("依赖安装成功")
      }else{
        spinner.fail("自动安装依赖失败, 请手动安装")
      }
    }else{
      console.log(chalk.yellowBright("请进入项目手动安装依赖"));
    }
  }


  installFuc = async (param) => {
    const { filePath, packageManager } = param;
    try {
        const stdout = await projectInstall({
            prefer: packageManager,
            cwd: filePath,
            stdio: "inherit"
        })

        return Promise.resolve(stdout);

    } catch (e) {
        return Promise.resolve(false);
    }
  }


  logCreateSucess(){
    console.log(`项目${chalk.yellow(this.prejectInfo.name)}创建成功`);
    console.log(`使用下面命令开始`);
    console.log(chalk.cyan(`${chalk.gray("$")} cd ${this.prejectInfo.name}`));
  }
  
}



module.exports = {
  CreatePrejectClass
}


